package ch.prokopovi.provider.places;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map.Entry;

import org.json.JSONArray;
import org.json.JSONObject;

import android.util.Log;
import ch.prokopovi.api.struct.BestRatesRecord;
import ch.prokopovi.db.PureConst;
import ch.prokopovi.provider.ProviderUtils;
import ch.prokopovi.struct.Master.CurrencyCode;
import ch.prokopovi.struct.Master.OperationType;
import ch.prokopovi.struct.Master.Region;
import ch.prokopovi.struct.SimpleBestRatesRecord;

class MoneyPointMdPlacesProvider extends AbstractPlacesProvider {

	private static final String LOG_TAG = "money.point.md provider";

	private static final String URL_FMT = "http://money.point.md/actions/ExchangeRates/GetRates?date=%1$tY-%1$tm-%1$td"; // 2013-07-16

	enum MoneyPointMdCurrency {
		USD(CurrencyCode.USD), //
		EUR(CurrencyCode.EUR), //
		RUB(CurrencyCode.RUR), //
		UAH(CurrencyCode.UAH), //
		RON(CurrencyCode.RON), //

		;

		private final CurrencyCode currency;

		private MoneyPointMdCurrency(CurrencyCode currency) {
			this.currency = currency;
		}

		CurrencyCode getCurrency() {
			return this.currency;
		}

		static MoneyPointMdCurrency get(String str) {
			for (MoneyPointMdCurrency val : values()) {
				if (val.name().equals(str)) {
					return val;
				}
			}
			return null;
		}
	}

	@Override
	public boolean isSupported(Region region) {
		return Region.CHISINAU.equals(region);
	}

	@Override
	public boolean isSupported(CurrencyCode currency) {

		for (MoneyPointMdCurrency mpmc : MoneyPointMdCurrency.values()) {
			if (mpmc.getCurrency().equals(currency)) {
				return true;
			}
		}

		return false;
	}

	@Override
	public List<Entry<Long, BestRatesRecord>> getPlaces(Region region) {

		String url = String.format(Locale.US, URL_FMT, new Date());
		try {
			String strJson = ProviderUtils.get(url);

			final List<Entry<Long, BestRatesRecord>> res = new ArrayList<Entry<Long, BestRatesRecord>>();

			JSONArray jsonRates = new JSONArray(strJson);
			for (int i = 0; i < jsonRates.length(); i++) {
				JSONObject jsonRate = jsonRates.getJSONObject(i);

				// Log.d(LOG_TAG, jsonRate.toString());

				// "OrganisationId" : "6ee27d36-617c-45e7-a7ea-c30a04546003",
				// "CurrencyId" : "2d88dfda-f4f7-44bb-accc-745de897d2e7",
				// "Parced" : "\/Date(1373922000000)\/",
				// "Nominal" : 1,
				// "Buy" : 12.52,
				// "Sell" : 12.55,
				// "BuyDiff" : 0.01,
				// "SellDiff" : 0.01,
				// "Visible" : true,
				// "Organisation" : null,
				// "Currency" : {
				// "CurrencyId" : "2d88dfda-f4f7-44bb-accc-745de897d2e7",
				// "Name" : "US Dollar",
				// "ShortName" : "USD",
				// "Nominal" : 1,
				// "SortIndex" : 1,
				// "Visible" : true
				// }

				String orgUid = jsonRate.getString("OrganisationId");
				Integer orgId = PureConst.toPositiveHashCode(orgUid);

				String strCurr = jsonRate.getJSONObject("Currency").getString(
						"ShortName");
				MoneyPointMdCurrency providerCurrency = MoneyPointMdCurrency
						.get(strCurr);

				if (providerCurrency == null) {
					Log.w(LOG_TAG, strCurr + " is not supported by provider");
					continue;
				}

				double buy = jsonRate.getDouble("Buy");
				double sell = jsonRate.getDouble("Sell");

				int currencyId = providerCurrency.getCurrency().getId();

				BestRatesRecord buyRecord = new SimpleBestRatesRecord(
						currencyId, OperationType.BUY.getId(), buy);
				res.add(createImmutableEntry(Long.valueOf(orgId), buyRecord));

				// Log.d(LOG_TAG, "--- " + orgId + " " + buyRecord);

				BestRatesRecord sellRecord = new SimpleBestRatesRecord(
						currencyId, OperationType.SELL.getId(), sell);
				res.add(createImmutableEntry(Long.valueOf(orgId), sellRecord));
			}

			return res;
		} catch (Exception e) {
			Log.d(LOG_TAG, "error during loading rates ", e);
		}

		return Collections.emptyList();
	}

}
